package com.wxzz.elearing.livetelecast.service.impl;

import cn.jmessage.api.JMessageClient;
import cn.jmessage.api.chatroom.CreateChatRoomResult;
import cn.jmessage.api.common.model.chatroom.ChatRoomPayload;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.huawei.vod.client.VodClient;
import com.huawei.vod.model.asset.CreateAssetByFileReq;
import com.huawei.vod.model.asset.UploadAssetRsp;
import com.wxzz.elearing.livetelecast.amqp.producer.LiveMessageProducer;
import com.wxzz.elearing.livetelecast.amqp.producer.PlatformLivetelecastProducer;
import com.wxzz.elearing.livetelecast.dto.*;
import com.wxzz.elearing.livetelecast.entity.*;
import com.wxzz.elearing.livetelecast.mapper.*;
import com.wxzz.elearing.livetelecast.service.IPlatformLivetelecastService;
import com.wxzz.elearing.livetelecast.service.openfeign.IUserOrderApiFeign;
import com.wxzz.elearing.livetelecast.service.openfeign.IWxUserApiFeign;
import com.wxzz.elearing.livetelecast.vo.PlatformLivetelecastFileVo;
import com.wxzz.elearing.livetelecast.vo.PlatformLivetelecastStatisticsVo;
import com.wxzz.elearing.livetelecast.vo.SendVodFileVo;
import com.wxzz.elearning.common.aop.Idempotent;
import com.wxzz.elearning.common.bean.SmsConfig;
import com.wxzz.elearning.common.constants.LiveConstants;
import com.wxzz.elearning.common.constants.OrderConstants;
import com.wxzz.elearning.common.constants.RedisConstants;
import com.wxzz.elearning.common.constants.RoomConstants;
import com.wxzz.elearning.common.dto.SystemMessageMqDto;
import com.wxzz.elearning.common.exception.ServiceException;
import com.wxzz.elearning.common.utils.*;
import com.wxzz.elearning.common.vo.JgPageVo;
import com.wxzz.elearning.common.vo.ReturnVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 平台直播 服务实现类
 * </p>
 *
 * @author
 * @since 2021-04-02
 */
@Service
@Slf4j
public class PlatformLivetelecastServiceImpl extends ServiceImpl<PlatformLivetelecastMapper, PlatformLivetelecast> implements IPlatformLivetelecastService {

    @Autowired
    private PlatformLivetelecastMapper platformLivetelecastMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private LivetelecastSummitMapper livetelecastSummitMapper;

    @Autowired
    private LivetelecastCategoryMapper livetelecastCategoryMapper;

    @Autowired
    private PlatformLivetelecastProducer platformLivetelecastProducer;

    @Autowired
    private LivetelecastRecordMapper livetelecastRecordMapper;

    @Transactional
    @Override
    public ReturnVO savePlatformLivetelecast(PlatformLivetelecast platformLivetelecast) {
        LivetelecastCategory livetelecastCategory = livetelecastCategoryMapper.selectById(platformLivetelecast.getLivetelecastCategoryIdFirst());
        if (livetelecastCategory == null) {
            throw new ServiceException("该id对应分类不存在");
        }
        platformLivetelecast.setStreamName(UUID.randomUUID().toString());
        // 允许回放录制
        if (platformLivetelecast.getIsAllowRecord()) {
            // 判断是否需要直播录制，如果需要则进行直播录制则调用华为云直播创建录制规则
            String ruleId = this.createRecordRule(platformLivetelecast.getStreamName());
            if (Strings.isNullOrEmpty(ruleId)) log.error("直播流{}创建直播录制规则ID错误", platformLivetelecast.getStreamName());
            platformLivetelecast.setRecordRuleId(ruleId);
        }


        if (platformLivetelecast.getPlatformLivetelecastFileVos() != null) {
            StringBuilder platformLivetelecastFiles = new StringBuilder();
            StringBuilder platformLivetelecastFileNames = new StringBuilder();
            StringBuilder platformLivetelecastFileSizes = new StringBuilder();
            for (PlatformLivetelecastFileVo platformLivetelecastFileVo : platformLivetelecast.getPlatformLivetelecastFileVos()) {
                platformLivetelecastFiles.append(platformLivetelecastFileVo.getLivetelecastFile()).append(",");
                platformLivetelecastFileNames.append(platformLivetelecastFileVo.getLivetelecastFileName()).append(",");
                platformLivetelecastFileSizes.append(platformLivetelecastFileVo.getLivetelecastFileSize()).append(",");
            }
            platformLivetelecast.setLivetelecastFile(platformLivetelecastFiles.toString());
            platformLivetelecast.setLivetelecastFileName(platformLivetelecastFileNames.toString());
            platformLivetelecast.setLivetelecastFileSize(platformLivetelecastFileSizes.toString());
        }
        //绑定活动
        Activity activity = activityMapper.selectById(platformLivetelecast.getActivityId());
        if (activity != null) {
            activity.setPlatformLivetelecastId(platformLivetelecast.getId());
            activityMapper.updateById(activity);
        }
        platformLivetelecastMapper.insert(platformLivetelecast);
        //峰会
        if (livetelecastCategory.getType() == 1) {
            LivetelecastSummit livetelecastSummit = new LivetelecastSummit();
            livetelecastSummit.setSummitDetail(platformLivetelecast.getSummitDetail());
            //直播议程
            if (platformLivetelecast.getSummitAgendaDataList() != null) {
                livetelecastSummit.setSummitAgenda(JSONObject.toJSONString(platformLivetelecast.getSummitAgendaDataList()));
            }
            //直播嘉宾
            if (platformLivetelecast.getSummitGuestDataList() != null) {
                livetelecastSummit.setSummitGuest(JSONObject.toJSONString(platformLivetelecast.getSummitGuestDataList()));
            }
            livetelecastSummit.setPlatformLivetelecastId(platformLivetelecast.getId());
            livetelecastSummitMapper.insert(livetelecastSummit);
        }

        //延时自动修改直播状态
        if (platformLivetelecast.getStartTime() != null && platformLivetelecast.getStartTime().isAfter(LocalDateTime.now())) {
            //发送消息
            platformLivetelecastProducer.updatePlatformLivetelecastStatus(platformLivetelecast.getId(), platformLivetelecast.getStartTime());
        }
        return new ReturnVO("新增平台直播成功", platformLivetelecast.getId());
    }

    @Transactional
    @Override
    public ReturnVO updatePlatformLivetelecast(PlatformLivetelecast platformLivetelecast) {
        LivetelecastCategory livetelecastCategory = livetelecastCategoryMapper.selectById(platformLivetelecast.getLivetelecastCategoryIdFirst());
        if (livetelecastCategory == null) {
            throw new ServiceException("该id对应分类不存在");
        }
        //绑定活动
        Activity activity = activityMapper.selectById(platformLivetelecast.getActivityId());
        if (activity != null) {
            activity.setPlatformLivetelecastId(platformLivetelecast.getId());
            activityMapper.updateById(activity);
        }
        //峰会
        if (livetelecastCategory.getType() == 1) {
            //先查询是否有存在的峰会封面
            LivetelecastSummit selectOne = livetelecastSummitMapper.selectOne(new LambdaQueryWrapper<LivetelecastSummit>().eq(LivetelecastSummit::getPlatformLivetelecastId, platformLivetelecast.getId()));
            if (selectOne != null) {
                livetelecastSummitMapper.deleteById(selectOne.getId());
            }
            //重新存放
            LivetelecastSummit livetelecastSummit = new LivetelecastSummit();
            livetelecastSummit.setSummitDetail(platformLivetelecast.getSummitDetail());
            //直播议程
            if (platformLivetelecast.getSummitAgendaDataList() != null) {
                livetelecastSummit.setSummitAgenda(JSONObject.toJSONString(platformLivetelecast.getSummitAgendaDataList()));
            }
            //直播嘉宾
            if (platformLivetelecast.getSummitGuestDataList() != null) {
                livetelecastSummit.setSummitGuest(JSONObject.toJSONString(platformLivetelecast.getSummitGuestDataList()));
            }
            livetelecastSummit.setPlatformLivetelecastId(platformLivetelecast.getId());
            livetelecastSummitMapper.insert(livetelecastSummit);
        }
        if (platformLivetelecast.getPlatformLivetelecastFileVos() != null) {
            StringBuilder platformLivetelecastFiles = new StringBuilder();
            StringBuilder platformLivetelecastFileNames = new StringBuilder();
            StringBuilder platformLivetelecastFileSizes = new StringBuilder();
            for (PlatformLivetelecastFileVo platformLivetelecastFileVo : platformLivetelecast.getPlatformLivetelecastFileVos()) {
                platformLivetelecastFiles.append(platformLivetelecastFileVo.getLivetelecastFile()).append(",");
                platformLivetelecastFileNames.append(platformLivetelecastFileVo.getLivetelecastFileName()).append(",");
                platformLivetelecastFileSizes.append(platformLivetelecastFileVo.getLivetelecastFileSize()).append(",");
            }
            platformLivetelecast.setLivetelecastFile(platformLivetelecastFiles.toString());
            platformLivetelecast.setLivetelecastFileName(platformLivetelecastFileNames.toString());
            platformLivetelecast.setLivetelecastFileSize(platformLivetelecastFileSizes.toString());
        }

        // 处理直播录制
        if (platformLivetelecast.getIsAllowRecord() != null) {
            if (platformLivetelecast.getIsAllowRecord()) {
                if (Strings.isNullOrEmpty(platformLivetelecast.getRecordRuleId())) {
                    String ruleId = this.createRecordRule(platformLivetelecast.getStreamName());
                    if (Strings.isNullOrEmpty(ruleId))
                        log.error("直播流{}创建直播录制规则ID错误", platformLivetelecast.getStreamName());
                    platformLivetelecast.setRecordRuleId(ruleId);
                }
            } else {
                // 判断是否需要直播录制，若不录制并且规则ID存在 则调用API删除规则
                if (!Strings.isNullOrEmpty(platformLivetelecast.getRecordRuleId())) {
                    this.deleteRecordRule(platformLivetelecast.getRecordRuleId());
                    platformLivetelecast.setRecordRuleId("");
                }
            }
        }
        platformLivetelecastMapper.updateById(platformLivetelecast);
        //延时自动修改直播状态
        if (platformLivetelecast.getStartTime() != null && platformLivetelecast.getStartTime().isAfter(LocalDateTime.now())) {
            //发送消息
            platformLivetelecastProducer.updatePlatformLivetelecastStatus(platformLivetelecast.getId(), platformLivetelecast.getStartTime());
        }
        return new ReturnVO("修改平台直播成功", platformLivetelecast.getId());
    }

    @Override
    public ReturnVO updateOnlinePersonNum(Long platformLivetelecastId, Integer update) {
        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(platformLivetelecastId);
        Optional.ofNullable(platformLivetelecast).orElseThrow(() -> new ServiceException("该直播已不存在"));
        if (update == 1) {
            //递增
            redisTemplate.opsForValue().increment(RedisConstants.LIVE_ONLINE_NUM + platformLivetelecastId, 1);
        }
        if (update == 0) {
            //递减
            redisTemplate.opsForValue().decrement(RedisConstants.LIVE_ONLINE_NUM + platformLivetelecastId, 1);
        }
        return new ReturnVO("在线人数修改成功", null);
    }

    @Override
    public ReturnVO<JgPageVo<List<PlatformLivetelecast>>> listPlatformLivetelecast(PlatformLivetelecastDto platformLivetelecastDto) {
        PageHelper.startPage(platformLivetelecastDto.getCurPage(), platformLivetelecastDto.getMaxPage());
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.orderByDesc("create_time");
        if (platformLivetelecastDto.getDocentId() != null) {
            queryWrapper.eq("docent_id", platformLivetelecastDto.getDocentId());
        }
        if (platformLivetelecastDto.getLivetelecastCategoryIdFirst() != null) {
            queryWrapper.eq("livetelecast_category_id_first", platformLivetelecastDto.getLivetelecastCategoryIdFirst());
        }
        if (platformLivetelecastDto.getLivetelecastCategoryIdSecond() != null) {
            queryWrapper.eq("livetelecast_category_id_second", platformLivetelecastDto.getLivetelecastCategoryIdSecond());
        }
        if (StringUtils.isNotBlank(platformLivetelecastDto.getLivetelecastName())) {
            queryWrapper.like("livetelecast_name", platformLivetelecastDto.getLivetelecastName() + "%");
        }
        if (platformLivetelecastDto.getLivetelecastStatus() != null) {
            queryWrapper.eq("livetelecast_status", platformLivetelecastDto.getLivetelecastStatus());
        }
        if (platformLivetelecastDto.getStartTime() != null && platformLivetelecastDto.getEndTime() != null) {
            queryWrapper.between("create_time", platformLivetelecastDto.getStartTime(), platformLivetelecastDto.getEndTime());
        }
        List<PlatformLivetelecast> platformLivetelecasts = platformLivetelecastMapper.selectList(queryWrapper);
        for (PlatformLivetelecast platformLivetelecast : platformLivetelecasts) {
            Activity activity = activityMapper.selectOne(new LambdaQueryWrapper<Activity>()
                    .eq(Activity::getPlatformLivetelecastId, platformLivetelecast.getId()));
            Optional.ofNullable(activity).ifPresent(a -> platformLivetelecast.setActivityId(a.getId()));
        }
        return new ReturnVO("平台直播列表查询成功", new JgPageVo<>(new PageInfo(platformLivetelecasts)));
    }

    @Autowired
    private ActivityMapper activityMapper;

    @Override
    public ReturnVO<JgPageVo<List<PlatformLivetelecast>>> wxListPlatformLivetelecast(WxPlatformLivetelecastDto wxPlatformLivetelecastDto) {
        PageHelper.startPage(wxPlatformLivetelecastDto.getCurPage(), wxPlatformLivetelecastDto.getMaxPage());
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.orderByDesc("create_time");
        if (wxPlatformLivetelecastDto.getIsPageDisplay() != null) {
            queryWrapper.eq("is_page_display", wxPlatformLivetelecastDto.getIsPageDisplay());
        }
        if (wxPlatformLivetelecastDto.getSort() != null && wxPlatformLivetelecastDto.getSort() == 0) {
            queryWrapper.orderByDesc("create_time");
        }
        if (wxPlatformLivetelecastDto.getSort() != null && wxPlatformLivetelecastDto.getSort() == 1) {
            queryWrapper.orderByAsc("create_time");
        }
        if (StringUtils.isNotBlank(wxPlatformLivetelecastDto.getLivetelecastName())) {
            queryWrapper.like("livetelecast_name", wxPlatformLivetelecastDto.getLivetelecastName() + "%");
        }
        if (wxPlatformLivetelecastDto.getStartTimeStart() != null && wxPlatformLivetelecastDto.getStartTimeEnd() != null) {
            queryWrapper.between("start_time", wxPlatformLivetelecastDto.getStartTimeStart(), wxPlatformLivetelecastDto.getStartTimeEnd());
        }
        if (wxPlatformLivetelecastDto.getLivetelecastStatus() != null) {
            queryWrapper.eq("livetelecast_status", wxPlatformLivetelecastDto.getLivetelecastStatus());
        }
        if (wxPlatformLivetelecastDto.getDocentId() != null) {
            queryWrapper.eq("docent_id", wxPlatformLivetelecastDto.getDocentId());
        }
        if (wxPlatformLivetelecastDto.getType() != null && wxPlatformLivetelecastDto.getType() == 1 && wxPlatformLivetelecastDto.getLivetelecastCategoryId() != null) {
            queryWrapper.eq("livetelecast_category_id_first", wxPlatformLivetelecastDto.getLivetelecastCategoryId());
        }
        if (wxPlatformLivetelecastDto.getType() != null && wxPlatformLivetelecastDto.getType() == 2 && wxPlatformLivetelecastDto.getLivetelecastCategoryId() != null) {
            queryWrapper.eq("livetelecast_category_id_second", wxPlatformLivetelecastDto.getLivetelecastCategoryId());
        }
        List<PlatformLivetelecast> platformLivetelecasts = platformLivetelecastMapper.selectList(queryWrapper);
        for (PlatformLivetelecast platformLivetelecast : platformLivetelecasts) {
            //查询如果有关联的活动则带活动id
            Activity activity = activityMapper.selectOne(new LambdaQueryWrapper<Activity>()
                    .eq(Activity::getPlatformLivetelecastId, platformLivetelecast.getId()));
            if (activity != null) {
                platformLivetelecast.setActivityId(activity.getId());
            }
            //查询讲师信息
            ReturnVO<String> stringReturnVO = wxUserApiFeign.selectDocentById(platformLivetelecast.getDocentId());
            JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
            platformLivetelecast.setDocentName(jsonObject.getString("docentName"));
            platformLivetelecast.setDocentPicture(jsonObject.getString("docentPicture"));
        }
        return new ReturnVO("平台直播列表查询成功", new JgPageVo<>(new PageInfo(platformLivetelecasts)));
    }

    @Autowired
    private IWxUserApiFeign wxUserApiFeign;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private WxUserPlatformLivetelecastMapper wxUserPlatformLivetelecastMapper;

    @Override
    public ReturnVO selectWxPlatformLivetelecastDetail(Long wxUserId, Long platformLivetelecastId) {
        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(platformLivetelecastId);
        if (platformLivetelecast == null) {
            throw new ServiceException("该直播间已不存在");
        }
        //增加累计访问量
        Long increment = redisTemplate.opsForValue().increment(RedisConstants.LIVE_VISIT_NUM + platformLivetelecastId, 1);
        //增加累计观看人数
        Long add = redisTemplate.opsForSet().add(RedisConstants.LIVE_VISIT_PERSON_NUM + platformLivetelecastId, JSONObject.toJSONString(wxUserId));
        platformLivetelecast.setOnlineNum(increment);
        platformLivetelecast.setVisitNum(add);
        platformLivetelecastMapper.updateById(platformLivetelecast);
        //查询是否有峰会对应该直播
        LivetelecastSummit livetelecastSummit = livetelecastSummitMapper.selectOne(new LambdaQueryWrapper<LivetelecastSummit>()
                .eq(LivetelecastSummit::getPlatformLivetelecastId, platformLivetelecastId));
        if (livetelecastSummit != null) {
            platformLivetelecast.setSummitDetail(livetelecastSummit.getSummitDetail());
            platformLivetelecast.setSummitAgendaDataList(JSONObject.parseObject(livetelecastSummit.getSummitAgenda(), List.class));
            platformLivetelecast.setSummitGuestDataList(JSONObject.parseObject(livetelecastSummit.getSummitGuest(), List.class));
        }
        //课件
        if (platformLivetelecast != null && StringUtils.isNotBlank(platformLivetelecast.getLivetelecastFile())) {
            if (platformLivetelecast.getLivetelecastFile() != null && platformLivetelecast.getLivetelecastFileName() != null && platformLivetelecast.getLivetelecastFileSize() != null) {
                String[] files = platformLivetelecast.getLivetelecastFile().split(",");
                String[] fileNames = platformLivetelecast.getLivetelecastFileName().split(",");
                String[] fileSizes = platformLivetelecast.getLivetelecastFileSize().split(",");
                List<PlatformLivetelecastFileVo> platformLivetelecastFileVos = Lists.newArrayList();
                for (int i = 0; i < files.length; i++) {
                    PlatformLivetelecastFileVo curriculumFileVo = new PlatformLivetelecastFileVo();
                    curriculumFileVo.setLivetelecastFile(files[i]);
                    curriculumFileVo.setLivetelecastFileName(fileNames[i]);
                    curriculumFileVo.setLivetelecastFileSize(fileSizes[i]);
                    platformLivetelecastFileVos.add(curriculumFileVo);
                }
                platformLivetelecast.setPlatformLivetelecastFileVos(platformLivetelecastFileVos);
            }
        }
        // 插入媒质
        platformLivetelecast.setRecords(livetelecastRecordMapper.getByLivetelecastId(platformLivetelecast.getId()));

        //给出推流地址
        platformLivetelecast.setLivePushUrl(LiveConstants.LIVE_PUSH_DOMAIN + "/" + platformLivetelecast.getStreamName());
        //设置直播倒计时
        if (platformLivetelecast.getStartTime() != null) {
            Long now = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
            Long start = platformLivetelecast.getStartTime().toEpochSecond(ZoneOffset.of("+8"));
            platformLivetelecast.setStartTimeSecond(start - now);
        }
        //查询用户是否预约
        Optional<WxUserPlatformLivetelecast> wxUserPlatformLivetelecastOptional = wxUserPlatformLivetelecastMapper.selectWxUserPlatformLivetelecastOne(wxUserId, platformLivetelecastId);
        wxUserPlatformLivetelecastOptional.ifPresent(wxUserPlatformLivetelecast -> {
            platformLivetelecast.setPayStatus(wxUserPlatformLivetelecast.getPayStatus());
            //如果当前在开播时间 则将观看状态改为已观看
            if (platformLivetelecast.getLivetelecastStatus() == 1) {
                wxUserPlatformLivetelecast.setIsWatch(1);
                wxUserPlatformLivetelecastMapper.updateById(wxUserPlatformLivetelecast);
                //直播的观看人数+1
                platformLivetelecast.setVisitNum(platformLivetelecast.getVisitNum() + 1);
                platformLivetelecastMapper.updateById(platformLivetelecast);
            }
        });
        //查看用户是否收藏
        PlatformLivetelecastCollect platformLivetelecastCollect = platformLivetelecastCollectMapper.selectOne(new LambdaQueryWrapper<PlatformLivetelecastCollect>()
                .eq(PlatformLivetelecastCollect::getWxUserId, wxUserId)
                .eq(PlatformLivetelecastCollect::getType, 0)
                .eq(PlatformLivetelecastCollect::getPlatformLivetelecastId, platformLivetelecast.getId()));
        if (platformLivetelecastCollect != null) {
            platformLivetelecast.setIsCollect(platformLivetelecastCollect.getIsCollect());
        }
        //查询讲师信息
        ReturnVO<String> stringReturnVO = wxUserApiFeign.selectDocentById(platformLivetelecast.getDocentId());
        JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
        platformLivetelecast.setDocentName(jsonObject.getString("docentName"));
        platformLivetelecast.setDocentPicture(jsonObject.getString("docentPicture"));
        return new ReturnVO("平台直播详情查询成功", platformLivetelecast);
    }

    @Autowired
    private PlatformLivetelecastCollectMapper platformLivetelecastCollectMapper;

    @Override
    public ReturnVO<PlatformLivetelecast> selectPlatformLivetelecastDetail(Long platformLivetelecastId) {
        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(platformLivetelecastId);
        Optional.ofNullable(platformLivetelecast).orElseThrow(() -> new ServiceException("该直播已不存在"));
        //查询该直播是否有对应活动
        Activity activity = activityMapper.selectOne(new LambdaQueryWrapper<Activity>()
                .eq(Activity::getPlatformLivetelecastId, platformLivetelecast.getId()));
        Optional.ofNullable(activity).ifPresent(a -> {
            platformLivetelecast.setActivityId(a.getId());
            platformLivetelecast.setActivityName(a.getActivityName());
        });
        //直播分类
        LivetelecastCategory first = livetelecastCategoryMapper.selectById(platformLivetelecast.getLivetelecastCategoryIdFirst());
        if (first != null) {
            platformLivetelecast.setLivetelecastCategoryIdFirstName(first.getCategoryName());
        }
        LivetelecastCategory second = livetelecastCategoryMapper.selectById(platformLivetelecast.getLivetelecastCategoryIdSecond());
        if (second != null) {
            platformLivetelecast.setLivetelecastCategoryIdSecondName(second.getCategoryName());
        }
        //查询是否有峰会对应该直播
        LivetelecastSummit livetelecastSummit = livetelecastSummitMapper.selectOne(new LambdaQueryWrapper<LivetelecastSummit>()
                .eq(LivetelecastSummit::getPlatformLivetelecastId, platformLivetelecastId));
        if (livetelecastSummit != null) {
            platformLivetelecast.setSummitDetail(livetelecastSummit.getSummitDetail());
            platformLivetelecast.setSummitAgendaDataList(JSONObject.parseObject(livetelecastSummit.getSummitAgenda(), List.class));
            platformLivetelecast.setSummitGuestDataList(JSONObject.parseObject(livetelecastSummit.getSummitGuest(), List.class));
        }
        //课件
        if (platformLivetelecast != null && StringUtils.isNotBlank(platformLivetelecast.getLivetelecastFile())) {
            if (StringUtils.isNotBlank(platformLivetelecast.getLivetelecastFile()) && StringUtils.isNotBlank(platformLivetelecast.getLivetelecastFileName()) && StringUtils.isNotBlank(platformLivetelecast.getLivetelecastFileSize())) {
                String[] files = platformLivetelecast.getLivetelecastFile().split(",");
                String[] fileNames = platformLivetelecast.getLivetelecastFileName().split(",");
                String[] fileSizes = platformLivetelecast.getLivetelecastFileSize().split(",");
                List<PlatformLivetelecastFileVo> platformLivetelecastFileVos = Lists.newArrayList();
                for (int i = 0; i < files.length; i++) {
                    PlatformLivetelecastFileVo curriculumFileVo = new PlatformLivetelecastFileVo();
                    curriculumFileVo.setLivetelecastFile(files[i]);
                    curriculumFileVo.setLivetelecastFileName(fileNames[i]);
                    curriculumFileVo.setLivetelecastFileSize(fileSizes[i]);
                    platformLivetelecastFileVos.add(curriculumFileVo);
                }
                platformLivetelecast.setPlatformLivetelecastFileVos(platformLivetelecastFileVos);
            }
        }
        // 插入媒质
        platformLivetelecast.setRecords(livetelecastRecordMapper.getByLivetelecastId(platformLivetelecast.getId()));
        return new ReturnVO("平台直播详情查询成功", platformLivetelecast);
    }

    @Override
    public ReturnVO deletePlatformLivetelecast(Long platformLivetelecastId) {
        livetelecastSummitMapper.deleteById(platformLivetelecastId);
        return new ReturnVO("平台直播删除成功", platformLivetelecastId);
    }

    @Override
    public ReturnVO sendVodFile(Long platformLivetelecastId) {
        // 初始化客户端
        VodClient vodClient = HuaweiLiveUtil.initVodClient();
        // 初始化创建媒资请求
        CreateAssetByFileReq req = HuaweiLiveUtil.buildCreateAssetReq();
        // 发送创建媒资请求
        UploadAssetRsp rsp = vodClient.createAssetByFile(req);
        if (rsp.getHttpCode() != 200) {
            throw new ServiceException("华为云创建媒资失败");
        }
        String assetId = rsp.getAssetId();

        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(platformLivetelecastId);
        platformLivetelecast.setAssetId(assetId);
        platformLivetelecastMapper.updateById(platformLivetelecast);
        //返回已授权的上传路径
        String videoUploadUrl = rsp.getVideoUploadUrl();
        SendVodFileVo sendVodFileVo = new SendVodFileVo();
        sendVodFileVo.setVideoUploadUrl(videoUploadUrl);
        sendVodFileVo.setAssetId(assetId);
        return new ReturnVO("媒资创建成功", sendVodFileVo);
    }

    @Override
    public ReturnVO confirmSend(String assetId) {
        //确认上传媒资 CREATED：创建成功。FAILED：创建失败。CANCELLED：创建取消。
        HuaweiLiveUtil.sendRequest("POST", "https://vod.cn-north-4.myhuaweicloud.com/v1.0/" + LiveConstants.PROJECT_ID + "/asset/status/uploaded",
                "{\n" +
                        "\"asset_id\":\"" + assetId + "\",\n" +
                        "\"status\":\"CREATED\"\n" +
                        "}");
        //查询视频url
        String entity = HuaweiLiveUtil.sendRequest("GET",
                "https://vod.cn-north-4.myhuaweicloud.com/v1.0/" + LiveConstants.PROJECT_ID + "/asset/details?asset_id=" + assetId,
                "{}");
        JSONObject jsonObject = JSONObject.parseObject(entity);
        String videoUrl = jsonObject.getJSONObject("base_info").getString("video_url");
        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectOne(new LambdaQueryWrapper<PlatformLivetelecast>()
                .eq(PlatformLivetelecast::getAssetId, assetId));
        if (platformLivetelecast != null) {
            platformLivetelecast.setReturnSeeUrl(videoUrl);
            platformLivetelecastMapper.updateById(platformLivetelecast);
        }
        return new ReturnVO("媒资确认上传成功", null);
    }

    @Autowired
    private IUserOrderApiFeign wxPayFeign;

    /**
     * 用户预约购买
     *
     * @param wxUserPlatformLivetelecastInsDto
     * @return
     */
    @Idempotent
    @Override
    public ReturnVO saveWxUserPlatformLivetelecast(String token, JSONObject jsonObject, WxUserPlatformLivetelecastInsDto wxUserPlatformLivetelecastInsDto) {
        if (wxUserPlatformLivetelecastInsDto.getPlatformLivetelecastId() == null) {
            throw new ServiceException("请传入直播间id");
        }
        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(wxUserPlatformLivetelecastInsDto.getPlatformLivetelecastId());
        if (platformLivetelecast == null) {
            throw new ServiceException("该直播间已不存在");
        }
        //接口幂等处理
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(RedisConstants.WX_USER_LIVE + token, token, 5, TimeUnit.SECONDS);
        if (!Boolean.TRUE.equals(aBoolean)) {
            throw new ServiceException("请重新进入确认是否已经支付成功,以免重复支付");
        }
        //创建预约信息
        WxUserPlatformLivetelecast wxUserPlatformLivetelecast = wxUserPlatformLivetelecastMapper.selectOne(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getWxUserId, jsonObject.getLong("id"))
                .eq(WxUserPlatformLivetelecast::getPlatformLivetelecastId, wxUserPlatformLivetelecastInsDto.getPlatformLivetelecastId())
                .eq(WxUserPlatformLivetelecast::getType, 0));
        //如果未生成过订单 则创建
        if (wxUserPlatformLivetelecast == null) {
            WxUserPlatformLivetelecast save = new WxUserPlatformLivetelecast();
            save.setIcon(jsonObject.getString("icon"));
            save.setRealName(jsonObject.getString("nickname"));
            save.setPhone(jsonObject.getString("phone"));
            save.setWxUserId(jsonObject.getLong("id"));
            save.setPlatformLivetelecastId(wxUserPlatformLivetelecastInsDto.getPlatformLivetelecastId());
            save.setInvitedWxUserId(wxUserPlatformLivetelecastInsDto.getInvitedWxUserId());
            //设置为直播
            save.setType(0);
            wxUserPlatformLivetelecastMapper.insert(save);
            wxUserPlatformLivetelecast = save;
        } else {
            //如果已支付 返回异常
            if (wxUserPlatformLivetelecast.getPayStatus() == 1) {
                throw new ServiceException("您已预约直播,请勿重复预约");
            }
        }
        //根据直播间状态判断预约类型
        //未开播时
        if (platformLivetelecast.getLivetelecastStatus() == 0) {
            //自己进入
            if (wxUserPlatformLivetelecastInsDto.getInvitedWxUserId() == null) {
                wxUserPlatformLivetelecast.setInvitedType(0);
            }
            //受邀请
            if (wxUserPlatformLivetelecastInsDto.getInvitedWxUserId() != null) {
                wxUserPlatformLivetelecast.setInvitedType(1);
            }
        }
        //直播中
        if (platformLivetelecast.getLivetelecastStatus() == 1) {
            //自己进入
            if (wxUserPlatformLivetelecastInsDto.getInvitedWxUserId() == null) {
                wxUserPlatformLivetelecast.setInvitedType(2);
            }
            //受邀请
            if (wxUserPlatformLivetelecastInsDto.getInvitedWxUserId() != null) {
                wxUserPlatformLivetelecast.setInvitedType(3);
            }
        }

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Map<String, String> map = new HashMap();
        map.put("ipaddress", IPUtils.getIpAddr(request));
        map.put("wxUserId", String.valueOf(jsonObject.getLong("id")));
        map.put("serialid", CodeGenerateUtils.generateProductCode());
        //如果免费直接返回购买成功
        if ("0.00".equals(platformLivetelecast.getLivetelecastPrice().toString())) {
            wxUserPlatformLivetelecast.setPayStatus(1);
            wxUserPlatformLivetelecastMapper.updateById(wxUserPlatformLivetelecast);
            return new ReturnVO("购买成功", 1);
        }
        map.put("businessId", String.valueOf(platformLivetelecast.getId()));
        map.put("payMoney", platformLivetelecast.getLivetelecastPrice().toString());
        map.put("orderTitle", "用户购买直播id:" + wxUserPlatformLivetelecastInsDto.getPlatformLivetelecastId());
        map.put("modelType", OrderConstants.MODEL_TYPE_LIVE.toString());
        map.put("userType", OrderConstants.USER_TYPE_PLATFORM_WX.toString());
        Map<String, String> result = wxPayFeign.orderPay(map);
        wxUserPlatformLivetelecast.setUserOrderId(Long.valueOf(result.get("orderId")));
        wxUserPlatformLivetelecastMapper.updateById(wxUserPlatformLivetelecast);
        return new ReturnVO("订单生成成功", result.get("returnJson"));
    }

    @Override
    public ReturnVO liveReward(JSONObject jsonObject, LiveRewardDto liveRewardDto) {
        WxUserPlatformLivetelecast wxUserPlatformLivetelecast = wxUserPlatformLivetelecastMapper.selectOne(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getWxUserId, jsonObject.getLong("id"))
                .eq(WxUserPlatformLivetelecast::getPlatformLivetelecastId, liveRewardDto.getPlatformLivetelecastId()));
        Optional.ofNullable(wxUserPlatformLivetelecast).orElseThrow(() -> new ServiceException("该用户未预约直播"));
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Map<String, String> map = new HashMap();
        map.put("ipaddress", IPUtils.getIpAddr(request));
        map.put("wxUserId", String.valueOf(jsonObject.getLong("id")));
        map.put("serialid", CodeGenerateUtils.generateProductCode());
        map.put("payMoney", liveRewardDto.getRewardAmount().toString());
        //存放用户预约直播关联id 用于回调修改打赏金额
        map.put("businessId", wxUserPlatformLivetelecast.getId().toString());
        map.put("orderTitle", "用户打赏直播id:" + liveRewardDto.getPlatformLivetelecastId());
        map.put("modelType", OrderConstants.MODEL_TYPE_LIVE_REWARD.toString());
        map.put("userType", OrderConstants.USER_TYPE_PLATFORM_WX.toString());
        Map<String, String> result = wxPayFeign.orderPay(map);
        wxUserPlatformLivetelecast.setUserOrderId(Long.valueOf(result.get("orderId")));
        return new ReturnVO("订单生成成功", result.get("returnJson"));
    }

    @Idempotent
    @Override
    public ReturnVO updateRewardAmount(Map<String, String> map) {
        WxUserPlatformLivetelecast result = wxUserPlatformLivetelecastMapper.selectById(Long.valueOf(map.get("businessId")));
        Optional.ofNullable(result).orElseThrow(() -> new ServiceException("该预约直播不存在"));
        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(result.getPlatformLivetelecastId());
        Optional.ofNullable(platformLivetelecast).orElseThrow(() -> new ServiceException("该直播已不存在"));
        Optional.ofNullable(platformLivetelecast.getDocentId()).orElseThrow(() -> new ServiceException("该直播无讲师"));
        result.setRewardAmount(result.getRewardAmount().add(new BigDecimal(map.get("rewardAmount"))));
        wxUserPlatformLivetelecastMapper.updateById(result);
        return new ReturnVO("赏金修改成功", platformLivetelecast.getDocentId());
    }

    @Override
    public ReturnVO<JgPageVo<List<WxUserPlatformLivetelecast>>> listInvitedWxUser(ListInvitedWxUserDto listInvitedWxUserDto) {
        PageHelper.startPage(listInvitedWxUserDto.getCurPage(), listInvitedWxUserDto.getMaxPage());
        List<WxUserPlatformLivetelecast> wxUserPlatformLivetelecasts = wxUserPlatformLivetelecastMapper.selectList(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getPlatformLivetelecastId, listInvitedWxUserDto.getPlatformLivetelecastId())
                .eq(WxUserPlatformLivetelecast::getType, 0)
                .ne(WxUserPlatformLivetelecast::getInvitationNum, 0)
                .orderByDesc(WxUserPlatformLivetelecast::getInvitationNum));
        return new ReturnVO("排行榜查询成功", new JgPageVo<>(new PageInfo(wxUserPlatformLivetelecasts)));
    }

    @Override
    public ReturnVO<WxUserPlatformLivetelecast> selectMyInvited(Long wxUserId, Long platformLivetelecastId) {
        WxUserPlatformLivetelecast wxUserPlatformLivetelecast = wxUserPlatformLivetelecastMapper.selectOne(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getPlatformLivetelecastId, platformLivetelecastId)
                .eq(WxUserPlatformLivetelecast::getType, 0)
                .eq(WxUserPlatformLivetelecast::getWxUserId, wxUserId)
                .eq(WxUserPlatformLivetelecast::getPayStatus, 1));
        List<WxUserPlatformLivetelecast> wxUserPlatformLivetelecasts = wxUserPlatformLivetelecastMapper.selectList(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getPlatformLivetelecastId, platformLivetelecastId)
                .eq(WxUserPlatformLivetelecast::getType, 0)
                .ne(WxUserPlatformLivetelecast::getInvitationNum, 0)
                .orderByDesc(WxUserPlatformLivetelecast::getInvitationNum)
                .select(WxUserPlatformLivetelecast::getWxUserId));
        //计算我的排名
        for (int i = 0; i < wxUserPlatformLivetelecasts.size(); i++) {
            if (wxUserId.equals(wxUserPlatformLivetelecasts.get(i).getWxUserId())) {
                wxUserPlatformLivetelecast.setMyRanking(i + 1);
            }
        }
        return new ReturnVO("我的邀请查询成功", wxUserPlatformLivetelecast);
    }

    @Override
    public ReturnVO<PlatformLivetelecastStatisticsVo> selectPlatformLivetelecastStatisticsVo(Long platformLivetelecastId) {
        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(platformLivetelecastId);
        Optional.ofNullable(platformLivetelecast).orElseThrow(() -> new ServiceException("该直播已不存在"));
        PlatformLivetelecastStatisticsVo platformLivetelecastStatisticsVo = new PlatformLivetelecastStatisticsVo();
        //累计访问量
        String liveVisitNum = redisTemplate.opsForValue().get(RedisConstants.LIVE_VISIT_NUM + platformLivetelecastId);
        if (StringUtils.isNotBlank(liveVisitNum)) {
            platformLivetelecastStatisticsVo.setLiveVisitNum(Long.valueOf(liveVisitNum));
        }
        //累计访问人数
        Long liveVisitPersonNum = redisTemplate.opsForSet().size(RedisConstants.LIVE_VISIT_PERSON_NUM + platformLivetelecastId);
        platformLivetelecastStatisticsVo.setLiveVisitPersonNum(liveVisitPersonNum);
        //查询用户关联直播数据
        List<WxUserPlatformLivetelecast> wxUserPlatformLivetelecasts = wxUserPlatformLivetelecastMapper.selectList(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getPlatformLivetelecastId, platformLivetelecastId)
                .eq(WxUserPlatformLivetelecast::getType, 0)
                .eq(WxUserPlatformLivetelecast::getPayStatus, 1));
        //人均在线时长
        double onlinePersonTime = 0;
        //获得打赏金额
        BigDecimal rewardAmount = new BigDecimal("0.00");
        //打赏次数
        Integer rewardNum = 0;
        for (WxUserPlatformLivetelecast wxUserPlatformLivetelecast : wxUserPlatformLivetelecasts) {
            onlinePersonTime = onlinePersonTime + wxUserPlatformLivetelecast.getSeeTime();
            if (!new BigDecimal("0.00").equals(wxUserPlatformLivetelecast.getRewardAmount())) {
                rewardNum = rewardNum + 1;
                rewardAmount = rewardAmount.add(wxUserPlatformLivetelecast.getRewardAmount());
            }
        }
        if (wxUserPlatformLivetelecasts.size() != 0) {
            onlinePersonTime = onlinePersonTime / (60 * wxUserPlatformLivetelecasts.size());
        }
        platformLivetelecastStatisticsVo.setOnlinePersonTime(onlinePersonTime);
        platformLivetelecastStatisticsVo.setRewardAmount(rewardAmount);
        platformLivetelecastStatisticsVo.setRewardNum(rewardNum);
        //消耗流量 todo 近30天
        platformLivetelecastStatisticsVo.setConsumptionFlow(HuaweiLiveUtil.getConsumptionFlow(platformLivetelecast.getStreamName()));
        //累计直播时长 回放占用空间
        Integer cumulativeLiveTime = 0;
        Integer playback = 0;
        List<LivetelecastRecord> livetelecastRecords = livetelecastRecordMapper.selectList(new LambdaQueryWrapper<LivetelecastRecord>()
                .eq(LivetelecastRecord::getLivetelecastId, platformLivetelecastId));
        for (LivetelecastRecord livetelecastRecord : livetelecastRecords) {
            cumulativeLiveTime = cumulativeLiveTime + livetelecastRecord.getRecordDuration();
            playback = playback + livetelecastRecord.getFileSize();
        }
        platformLivetelecastStatisticsVo.setCumulativeLiveTime((double) cumulativeLiveTime / 60);
        platformLivetelecastStatisticsVo.setPlayback((double) playback / (1024 * 1024 * 1024));
        return new ReturnVO("查询该直播对应的统计数据成功", platformLivetelecastStatisticsVo);
    }

    public static void main(String[] args) {
        System.out.println((double) 42/(60*60));
    }

    @Override
    public Integer countByPlatformLivetelecast() {
        return platformLivetelecastMapper.selectCount(new QueryWrapper<>());
    }

    @Override
    public Integer countByActivity() {
        return activityMapper.selectCount(new QueryWrapper<>());
    }

    @Override
    public Integer selectPlatformLivetelecastTimeByDocentId(Long docentId) {
        List<LivetelecastRecord> livetelecastRecords = livetelecastRecordMapper.selectList(new LambdaQueryWrapper<LivetelecastRecord>()
                .eq(LivetelecastRecord::getDocentId, docentId));
        Integer recordDuration = 0;
        for (LivetelecastRecord livetelecastRecord : livetelecastRecords) {
            recordDuration = recordDuration + livetelecastRecord.getRecordDuration();
        }
        return recordDuration;
    }

    @Override
    public Integer selectPlatformLivetelecastNumByDocentId(Long docentId) {
        return platformLivetelecastMapper.selectCount(new LambdaQueryWrapper<PlatformLivetelecast>()
                .eq(PlatformLivetelecast::getDocentId, docentId));
    }

    @Override
    public ReturnVO<JgPageVo<List<PlatformLivetelecast>>> listMyPlatformLivetelecast(Long wxUserId, MyWxPlatformLivetelecastDto myWxPlatformLivetelecastDto) {
        PageHelper.startPage(myWxPlatformLivetelecastDto.getCurPage(), myWxPlatformLivetelecastDto.getMaxPage());
        List<WxUserPlatformLivetelecast> wxUserPlatformLivetelecasts = wxUserPlatformLivetelecastMapper.selectList(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getWxUserId, wxUserId)
                .eq(WxUserPlatformLivetelecast::getType, 0)
                .eq(WxUserPlatformLivetelecast::getPayStatus, 1)
                //.and(qw -> qw.eq(WxUserPlatformLivetelecast::getInvitedType, 1).or().eq(WxUserPlatformLivetelecast::getInvitedType, 3))
                .orderByDesc(WxUserPlatformLivetelecast::getCreateTime));
        List<PlatformLivetelecast> livetelecasts = Lists.newArrayList();
        for (WxUserPlatformLivetelecast wxUserPlatformLivetelecast : wxUserPlatformLivetelecasts) {
            PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(wxUserPlatformLivetelecast.getPlatformLivetelecastId());
            livetelecasts.add(platformLivetelecast);
        }
        JgPageVo<Object> objectJgPageVo = new JgPageVo<>(new PageInfo(wxUserPlatformLivetelecasts));
        objectJgPageVo.setData(livetelecasts);
        return new ReturnVO("预约列表查询成功", objectJgPageVo);
    }

    @Override
    public ReturnVO<JgPageVo<List<Activity>>> listMyActivity(Long wxUserId, MyWxPlatformLivetelecastDto myWxPlatformLivetelecastDto) {
        PageHelper.startPage(myWxPlatformLivetelecastDto.getCurPage(), myWxPlatformLivetelecastDto.getMaxPage());
        List<WxUserPlatformLivetelecast> wxUserPlatformLivetelecasts = wxUserPlatformLivetelecastMapper.selectList(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getWxUserId, wxUserId)
                .eq(WxUserPlatformLivetelecast::getType, 1)
                .eq(WxUserPlatformLivetelecast::getPayStatus, 1)
                //.and(qw -> qw.eq(WxUserPlatformLivetelecast::getInvitedType, 1).or().eq(WxUserPlatformLivetelecast::getInvitedType, 3))
                .orderByDesc(WxUserPlatformLivetelecast::getCreateTime));
        List<Activity> activities = Lists.newArrayList();
        for (WxUserPlatformLivetelecast wxUserPlatformLivetelecast : wxUserPlatformLivetelecasts) {
            Activity activity = activityMapper.selectById(wxUserPlatformLivetelecast.getActivityId());
            if (activity != null) {
                activities.add(activity);
            }
        }
        JgPageVo<Object> objectJgPageVo = new JgPageVo<>(new PageInfo(activities));
        objectJgPageVo.setData(activities);
        return new ReturnVO("预约列表查询成功", objectJgPageVo);
    }


    //极光初始化
    JMessageClient client = new JMessageClient(RoomConstants.APP_KEY, RoomConstants.MASTER_SECRET);

    @Override
    public ReturnVO<Map> initIM(Long platformLivetelecastId) {
        PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(platformLivetelecastId);
        if (platformLivetelecast == null) {
            throw new ServiceException("该直播间不存在");
        }
        if (platformLivetelecast.getRoomId() == null) {
            try {
                //聊天室懒加载
                CreateChatRoomResult chatRoom = client.createChatRoom(ChatRoomPayload.newBuilder()
                        .setOwnerUsername("admin")
                        .setName(platformLivetelecast.getLivetelecastName())
                        .build());
                platformLivetelecast.setRoomId(chatRoom.getChatroom_id());
                platformLivetelecastMapper.updateById(platformLivetelecast);
            } catch (Exception e) {
                throw new ServiceException("聊天室初始化异常:" + e.getMessage());
            }
        }
        Map<String, String> map = new HashMap<>();
        String uuid = UUID.randomUUID().toString();
        String time = String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        map.put("appkey", RoomConstants.APP_KEY);
        map.put("random_str", uuid);
        map.put("signature", MD5Util.md5Encrypt32Upper("appkey=90404644792112144baf94ae&timestamp=" + time + "&random_str=" + uuid + "&key=" + RoomConstants.MASTER_SECRET));
        map.put("timestamp", time);
        map.put("roomId", String.valueOf(platformLivetelecast.getRoomId()));
        return new ReturnVO("聊天室初始化成功", map);
    }

    @Idempotent
    @Transactional
    @Override
    public ReturnVO<String> handlerNotifyLive(Long userOrderId) {
        WxUserPlatformLivetelecast wxUserPlatformLivetelecast = wxUserPlatformLivetelecastMapper.selectOne(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getUserOrderId, userOrderId));
        Optional.ofNullable(wxUserPlatformLivetelecast).orElseThrow(() -> new ServiceException("该订单id对应信息不存在"));
        if (wxUserPlatformLivetelecast.getPayStatus() != null && wxUserPlatformLivetelecast.getPayStatus() == 0) {
            //设为已支付
            wxUserPlatformLivetelecast.setPayStatus(1);
            wxUserPlatformLivetelecastMapper.updateById(wxUserPlatformLivetelecast);
            //查询邀请人 todo 只有直播有邀请 待确定
            if (wxUserPlatformLivetelecast.getInvitedWxUserId() != null) {
                WxUserPlatformLivetelecast invitedUser = wxUserPlatformLivetelecastMapper.selectOne(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                        .eq(WxUserPlatformLivetelecast::getType, 0)
                        .eq(WxUserPlatformLivetelecast::getPlatformLivetelecastId, wxUserPlatformLivetelecast.getPlatformLivetelecastId())
                        .eq(WxUserPlatformLivetelecast::getWxUserId, wxUserPlatformLivetelecast.getInvitedWxUserId())
                        .eq(WxUserPlatformLivetelecast::getPayStatus, 1));
                if (invitedUser != null) {
                    invitedUser.setInvitationNum(invitedUser.getInvitationNum() + 1);
                    wxUserPlatformLivetelecastMapper.updateById(invitedUser);
                }
            }
            //查询直播
            PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.selectById(wxUserPlatformLivetelecast.getPlatformLivetelecastId());
            //如果是预约 则预约人数+1
            if ((wxUserPlatformLivetelecast.getInvitedType() != null && wxUserPlatformLivetelecast.getInvitedType() == 0) ||
                    (wxUserPlatformLivetelecast.getInvitedType() != null && wxUserPlatformLivetelecast.getInvitedType() == 1)) {
                if (platformLivetelecast != null) {
                    platformLivetelecast.setSubscribeNum(platformLivetelecast.getSubscribeNum() + 1);
                    platformLivetelecastMapper.updateById(platformLivetelecast);
                }
            }
            if (platformLivetelecast != null) {
                //发送消息
                SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
                systemMessageMqDto.setPhones(new ArrayList<String>() {
                    {
                        add(wxUserPlatformLivetelecast.getPhone());
                    }
                });
                systemMessageMqDto.setTemplateId(SmsConfig.liveSaveSuccessId);
                systemMessageMqDto.setParams(new ArrayList<String>() {
                    {
                        add(platformLivetelecast.getLivetelecastName());
                        add(platformLivetelecast.getStartTime().toLocalDate().toString());
                        add(platformLivetelecast.getStartTime().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
                    }
                });
                systemMessageMqDto.setMessageDetail("您预约的" + platformLivetelecast.getLivetelecastName() + "直播于" + platformLivetelecast.getStartTime().toLocalDate().toString() + "  " + platformLivetelecast.getStartTime().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "时开播,请您及时收看");
                systemMessageMqDto.setMessageTitle("直播-预约成功");
                systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                    {
                        add(wxUserPlatformLivetelecast.getWxUserId());
                    }
                });
                liveMessageProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
            }
            //查询活动
            Activity activity = activityMapper.selectById(wxUserPlatformLivetelecast.getActivityId());
            if (activity != null) {
                //发送消息
                SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
                systemMessageMqDto.setPhones(new ArrayList<String>() {
                    {
                        add(wxUserPlatformLivetelecast.getPhone());
                    }
                });
                systemMessageMqDto.setTemplateId(SmsConfig.activitySaveSuccessId);
                systemMessageMqDto.setParams(new ArrayList<String>() {
                    {
                        add(activity.getActivityName());
                        add(activity.getActivityStartTime().toLocalDate().toString());
                        add(activity.getActivityStartTime().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
                    }
                });
                systemMessageMqDto.setMessageDetail("您预约的" + activity.getActivityTitle() + "活动于" + activity.getActivityStartTime().toLocalDate().toString() + "  " + activity.getActivityStartTime().format(DateTimeFormatter.ofPattern("HH:mm:ss")) + "时开播,请您及时收看");
                systemMessageMqDto.setMessageTitle("活动-预约成功");
                systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                    {
                        add(wxUserPlatformLivetelecast.getWxUserId());
                    }
                });
                liveMessageProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
            }
        }
        return new ReturnVO("购买状态修改成功", null);
    }

    @Autowired
    private LiveMessageProducer liveMessageProducer;

    @Override
    public Boolean livePushCallback(LivePushCallbackEntity callbackEntity) {

        log.info("当前接收到的直播推流: {}", callbackEntity.toString());

        String PUBLISH = "PUBLISH"; // 开播
        String PUBLISH_DONE = "PUBLISH_DONE"; // 停播

        if (!Strings.isNullOrEmpty(callbackEntity.getStream())) {

            // 获取直播记录
            PlatformLivetelecast platformLivetelecast = platformLivetelecastMapper.getByStreamName(callbackEntity.getStream());
            if (platformLivetelecast == null) {
                log.error("当前接收到的直播推流未匹配数据库streamName：{}", callbackEntity.getStream());
                return false;
            }

            if (PUBLISH.equals(callbackEntity.getEvent())) {
                // 已开播
                /*PlatformLivetelecast saveObj = new PlatformLivetelecast();
                saveObj.setId(platformLivetelecast.getId());
                saveObj.setPushStatus(1); // 设置开播状态
                platformLivetelecastMapper.updateById(saveObj);*/
                //发送消息
                platformLivetelecastProducer.updatePushStatus(platformLivetelecast.getId(), 1, 30);
                log.info("直播{},id:{} 提交延迟更新推流状态（延迟修改为开播状态）", callbackEntity.getStream(), platformLivetelecast.getId());
                return true;
            } else if (PUBLISH_DONE.equals(callbackEntity.getEvent())) {
                // 已停播
                /*PlatformLivetelecast saveObj = new PlatformLivetelecast();
                saveObj.setId(platformLivetelecast.getId());
                saveObj.setPushStatus(2); // 设置停播状态
                platformLivetelecastMapper.updateById(saveObj);*/
                //发送消息
                platformLivetelecastProducer.updatePushStatus(platformLivetelecast.getId(), 2, 30);
                log.info("直播{},id:{} 提交延迟更新推流状态（延迟修改为停播状态） ", callbackEntity.getStream(), platformLivetelecast.getId());
                return true;
            } else {
                // 未知状态
                log.error("未知推流状态 直播流:{}，状态:{}", callbackEntity.getStream(), callbackEntity.getEvent());
            }

        } else {
            log.error("当前直播推流回调未获取到streamName: {}", callbackEntity.toString());
        }

        return false;
    }

    @Override
    public ReturnVO seeReturn(Long wxUserId, SeeReturnDto seeReturnDto) {
        WxUserPlatformLivetelecast wxUserPlatformLivetelecast = wxUserPlatformLivetelecastMapper.selectOne(new LambdaQueryWrapper<WxUserPlatformLivetelecast>()
                .eq(WxUserPlatformLivetelecast::getWxUserId, wxUserId)
                .eq(WxUserPlatformLivetelecast::getPlatformLivetelecastId, seeReturnDto.getPlatformLivetelecastId()));
        Optional.ofNullable(wxUserPlatformLivetelecast).orElseThrow(() -> new ServiceException("该用户未预约直播"));
        wxUserPlatformLivetelecast.setSeeTime(wxUserPlatformLivetelecast.getSeeTime() + seeReturnDto.getSeeTime());
        wxUserPlatformLivetelecastMapper.updateById(wxUserPlatformLivetelecast);
        return new ReturnVO("直播观看成功", wxUserPlatformLivetelecast.getId());
    }


    // ========== 内部方法 ==========

    /**
     * 新增直播录制
     *
     * @param stream
     * @return
     */
    private String createRecordRule(String stream) {

        JSONObject requestObj = new JSONObject();
        requestObj.put("publish_domain", LiveConstants.LIVE_PUSH_DOMAIN_RAW);
        requestObj.put("app", "live");
        requestObj.put("stream", stream);
        requestObj.put("record_type", "CONTINUOUS_RECORD");

        // 录制配置
        JSONObject defaultRecordConfig = new JSONObject();
        JSONArray recordFormat = new JSONArray();
        recordFormat.add("MP4");
        defaultRecordConfig.put("record_format", recordFormat);
        JSONObject mp4Config = new JSONObject();
        mp4Config.put("record_cycle", 300);
        defaultRecordConfig.put("mp4_config", mp4Config);

        // obs配置
        JSONObject recordObsFileAddr = new JSONObject();
        recordObsFileAddr.put("bucket", "wxzz-live");
        recordObsFileAddr.put("location", "cn-north-4");
        recordObsFileAddr.put("object", "live/");

        defaultRecordConfig.put("obs_addr", recordObsFileAddr);
        requestObj.put("default_record_config", defaultRecordConfig);

        log.info("当前请求参数: {}", requestObj.toJSONString());

        String entity = HuaweiLiveUtil.sendRequest("POST",
                "https://live.cn-north-4.myhuaweicloud.com/v1/" + LiveConstants.PROJECT_ID + "/record/rules", requestObj.toJSONString());
        log.info("创建录制规则返回结果: {}", entity);
        JSONObject res = JSONObject.parseObject(entity);
        if (res.get("id") != null && !Strings.isNullOrEmpty(res.get("id").toString())) {
            log.info("当前创建的录制规则id： {}", res.get("id").toString());
            return res.get("id").toString();
        } else {
            log.error("华为返回错误结果: {}", entity);
        }
        return "";
    }

    /**
     * 删除录制规则ID
     *
     * @param ruleId
     * @return
     */
    private String deleteRecordRule(String ruleId) {

        String entity = HuaweiLiveUtil.sendRequest("DELETE",
                "https://live.cn-north-4.myhuaweicloud.com/v1/" + LiveConstants.PROJECT_ID + "/record/rules/" + ruleId, "{}");

        log.info("删除录制规则回调： {}", entity);
        return "";
    }

}
